/** ****************************************************************************
@defgroup RC RX
@ingroup RC_RX
@brief 遥控接收驱动
@addtogroup RC_RX
@{
*******************************************************************************/

#ifndef _RC_RX_H_
#define _RC_RX_H_

#include "nonos.h"
#include "rc_codec.h"


typedef enum {
	RCRX_STATE_IDLE = 0,	// 未启动
	RCRX_STATE_RECORD,		// 正在进行原始波形记录
	RCRX_STATE_SCAN,		// 正在编码扫描
	RCRX_STATE_ENCODE,		// 正在编码
	RCRX_STATE_MAX,
} rcrx_state_t;

/// 收到红外码后回调函数原型
/// @param code 收到的红外码缓冲区。注意这个缓冲区是动态的，回调函数返回后将不再可用！
/// @param len 收到的红外码长度
/// @return 返回 true，表示继续接收；否则停止接收
typedef bool (*FUNC_RcRxCodeHandler)(uint8_t *code, uint16_t len);

/// 遥控接收驱动
typedef struct {
	/// 需要外部提供的回调函数和资源
	/// 脉冲缓冲区
	rc_pulse_buffer_t *pb;
	/// 使能 EXTI 中断
	FUNC_GPIO_EXTI_Enable extiEnable;
	/// 禁止 EXTI 中断
	FUNC_GPIO_EXTI_Disable extiDisable;
	/// 读取当前电平
	FUNC_GPIO_ReadIn getLevel;
	
	/// 脉冲捕获过滤条件
	/// 要跳过的帧数：遥控器(特别是无线遥控器)刚刚开始发射时，因为刚上电电压不稳，信号质量可能会很差，最好不要用来做分析，需要跳过前面的几帧！！！
	uint16_t SKIP_FRAME;
	/// 最小脉冲宽度(小于此则认为是毛刺)
	uint16_t WIDTH_MIN;
	/// 最大脉冲宽度(大于此则无法处理)
	uint16_t WIDTH_MAX;
	/// 起始捕获脉冲宽度(us)
	uint16_t LEAD_MIN;
	/// 停止捕获脉冲宽度(us)(遇到就认为结束)
	uint16_t TAIL_MIN;
	/// 在进行脉冲宽度分类时，允许的分类误差百分比(单位:1%)
	uint16_t PWERR;
	
	/// 脉冲捕获运行时
	/// 应用层收到红外码后回调函数
	FUNC_RcRxCodeHandler codeHandler;
	/// 状态
	rcrx_state_t state;
	/// 上一个电平变化的时间(us)
	uint32_t lastUs;
	/// 所有脉冲总宽度us(不算头和尾的时间)
	uint32_t totalWidth;
	/// 最小脉冲
	uint16_t min;
	/// 最大脉冲
	uint16_t max;
	/// 已经跳过的帧数
	uint8_t skipFrame;
	/// 最后一个脉冲电平
	uint8_t lastLevel;
} driver_rcrx_t;

/**
 * @brief 初始化
 * @param dev 驱动数据结构指针
 */
std_err_t rcrx_init(driver_rcrx_t* dev);

/**
 * @brief 开始接收
 * @param dev 驱动数据结构指针
 */
void rcrx_start(driver_rcrx_t* dev, FUNC_RcRxCodeHandler codeHandler);

/**
 * @brief 停止接收
 * @param dev 驱动数据结构指针
 */
void rcrx_stop(driver_rcrx_t* dev);

/**
 * @brief 中断处理
 * @param dev 驱动数据结构指针
 */
void rcrx_irqHandler(driver_rcrx_t* dev);


#endif  // _RC_RX_H_
/// @}
